package edu.maping.easy.painter;

import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import processing.core.PApplet;

import edu.maping.easy.gui.CircleButton;
import edu.maping.easy.gui.GuiFactory;
import edu.maping.easy.io.KeyBoardInteraction;
import edu.maping.easy.model.MouseInteraction;
import edu.maping.easy.model.Point;
import edu.maping.easy.model.Thing;
import edu.maping.easy.sequence.ActionConf;
import edu.maping.easy.sequence.ActionEvent;
import edu.maping.easy.sequence.ActionEventList;
import edu.maping.easy.sequence.SequenceStep;
import fisica.FBody;

public class PainterDelegateEditor implements MouseInteraction {

	private SequenceStep thingActionEvent;
	private SequenceStep lastThingActionEvent;

	private List<CircleButton> buttons = new ArrayList<CircleButton>();
	private List<ActionEvent> actionConfs = new ArrayList<ActionEvent>();

	public GuiFactory guiFactory = null;

	private Point startSelectedPoint = null;
	private Point selectedConf = null;
	private ActionEvent actionEvent = null;

	@Override
	public void KeyPressed(KeyBoardInteraction keyBoardInteraction) {
		// TODO Auto-generated method stub

	}

	@Override
	public void editKeyPressed(int key, Thing thing) {
		// TODO Auto-generated method stub

	}

	@Override
	public boolean mouseClicked(int mouseX, int mouseY, Thing newThing,
			MouseEvent mouseEvent) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void mouseDragged(int mouseX, int mouseY, Thing newThing) {

		if (startSelectedPoint != null) {
			int dx = startSelectedPoint.getX() - mouseX;
			int dy = startSelectedPoint.getY() - mouseY;
			selectedConf.move(-dx, -dy);
			startSelectedPoint.setXY(mouseX, mouseY);
		}
	}

	@Override
	public void mouseMoved(int mouseX, int mouseY) {
		// TODO Auto-generated method stub

	}

	@Override
	public void mousePreassed(int mouseX, int mouseY, Thing newThing) {

		FBody painterButtonConf = null;
		ActionEvent actionConfTemp = null;
		FBody hovered = guiFactory.getWorldGUI().getBody(mouseX, mouseY);
		for (int index = 0; index < buttons.size(); index++) {
			if (buttons.get(index) == hovered) {
				painterButtonConf = hovered;
				actionConfTemp = actionConfs.get(index);
				break;
			}
		}

		if (painterButtonConf != null) {
			startSelectedPoint = new Point((int) painterButtonConf.getX(),
					(int) painterButtonConf.getY());
			// CircleButton circleButton = (CircleButton) hovered;
			// selectedConf = guiFactory.newCircleButton(circleButton);
			selectedConf = new Point((int) painterButtonConf.getX(),
					(int) painterButtonConf.getY());
			actionEvent = actionConfTemp;
			// selectedConf.setFill(selectedConf.getColor(), 0.5F);
		}
	}

	@Override
	public void mouseReleased(int mouseX, int mouseY, Thing hoveredThing) {

		if (hoveredThing != null && startSelectedPoint != null) {
			ActionEvent actionEventCopy = actionEvent.copy();
			ActionEventList actionEventList = thingActionEvent.actionEventMap
					.get(hoveredThing);

			if (actionEventList == null) {
				actionEventList = new ActionEventList();
				thingActionEvent.actionEventMap.put(hoveredThing,
						actionEventList);
			}

			actionEventList.add(actionEventCopy);
			
			updateButtons(guiFactory);
		}

		selectedConf = null;
		startSelectedPoint = null;
	}

	@Override
	public void mouseWheelMoved(MouseWheelEvent e) {

	}

	public void draw(PApplet applet) {

		// Solo creamos los botones cuando cambiemos de momento
		if (isChangedLastAction()) {

			deleteOlderButtons(guiFactory);

			createNewButtons(guiFactory);

			lastThingActionEvent = thingActionEvent;
		}

		if (selectedConf != null) {
			applet.fill(255, 0, 0, 0.5F);
			applet.ellipse(selectedConf.getX(), selectedConf.getY(), 10, 10);
		}
	}

	private boolean isChangedLastAction() {
		return lastThingActionEvent == null && thingActionEvent != null
				|| lastThingActionEvent != thingActionEvent;
	}

	public void createNewButtons(GuiFactory guiFactory) {
		// Y ahroa generamos los nuevos
		if (thingActionEvent == null)
			return;

		Iterator<Thing> set = thingActionEvent.actionEventMap.keySet()
				.iterator();

		while (set.hasNext()) {

			Thing thing = set.next();
			ActionEventList actionEventList = thingActionEvent.actionEventMap
					.get(thing);

			int y = thing.y;
			int x = thing.x;

			for (ActionEvent actionEvent : actionEventList) {
				CircleButton circleButton = guiFactory.newCircleButton(
						actionEvent.painterContainer.painterDelegate.getName(), x, y, 20);
				y -= 30;
				buttons.add(circleButton);
				actionConfs.add(actionEvent);
			}

		}
	}
	
	public void updateButtons(GuiFactory guiFactory){
		deleteOlderButtons(guiFactory);
		createNewButtons(guiFactory);
	}

	public void deleteOlderButtons(GuiFactory guiFactory) {
		// Primero borramos los anteriores
		for (int index = 0; index < buttons.size(); index++) {
			guiFactory.getWorldGUI().remove(buttons.get(index));
		}
		buttons.clear();
		actionConfs.clear();
	}

	public void setThingActionEvent(SequenceStep thingActionEvent) {
		this.thingActionEvent = thingActionEvent;
	}

}
